﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.IO;
using Lizk.SimpleHUD;
using System.Threading;
using SharpMedia.Controls;
using Lizk.Utilities;
using MediaData;

namespace SharpMedia.Pages
{
    public class OverlayPage2 : MediaPage
    {
        public static DiskMonitor diskMonitor = new DiskMonitor();
        object objectLock = new object();
        TripTrigger volumeBoxTrigger = new TripTrigger(new TimeSpan(0, 0, 0, 3));
        TripTrigger removeTrigger = new TripTrigger(new TimeSpan(0, 0, 0, 1));

        HUDImage background;
        HUDContainerSimple warningBox, bottomBox, hdBox;
        HUDMoveList hdList;

        public OverlayPage2()
            : base(null)
        {
            //SharpMedia.Form.WindowsMessages += new XNAHUDEngine.XNAForm.WndProcHandler(delegate(ref System.Windows.Forms.Message m, ref bool call) { diskMonitor.PreFilterMessage(ref m); });

            diskMonitor.DiskFound += new DeviceChangedEventHandler(diskMonitor_DiskFound);
            diskMonitor.DiskRemoved += new DeviceChangedEventHandler(diskMonitor_DiskRemoved);
            


            background = new HUDImage("white.png")
            {
                ConstrainProportions = false,
                Color = ColorS.Black,
                Size = Size,
                Anchor = Anchor.All,
                Alpha = 0
            };
            Add(background);

            bottomBox = new HUDContainerSimple();
            bottomBox.Location = new PointS(0, Size.Height - 128);
            bottomBox.Size = new SizeS(Size.Width, 128);
            bottomBox.Anchor = Anchor.All ^ Anchor.Top;
            Add(bottomBox);


            warningBox = new HUDContainerSimple();
            warningBox.Size = new SizeS(400, 64);
            warningBox.Alpha = 0;
            bottomBox.Add(new HUDCentering(bottomBox, warningBox));

            HUDImage wBackImage = new HUDImage("selection.png");
            wBackImage.Size = warningBox.Size; 
            
            wBackImage.ConstrainProportions = false;
            wBackImage.Alpha = 255;
            warningBox.Add(wBackImage);

            
            HUDImage noImage = new HUDImage("no.png");
            noImage.Size = new SizeS(64, 64);
            warningBox.Add(noImage);

            HUDLabel noWarning = new HUDLabel("Database is updating, please wait...", "tahoma23b");
            noWarning.Size = new SizeS(338, 64);
            noWarning.Location = new PointS(64, 0);
            noWarning.Alignment = Lizk.SimpleHUD.Alignment.VCenter | Lizk.SimpleHUD.Alignment.Left;
            warningBox.Add(noWarning);


            hdBox = new HUDContainerSimple();
            hdBox.Size = new SizeS(200, Size.Height);
            hdBox.Anchor = Anchor.All ^ Anchor.Left;
            hdBox.Location = new PointS(Size.Width, 0);
            hdBox.MovementSpeed = 10f;
            Add(hdBox);

            hdList = new HUDMoveList(new SizeS(200, 70), false);
            hdList.Size = new SizeS(200, 70);
            
            hdBox.Add(new HUDCentering(hdBox, hdList));

            volumeBoxTrigger.FirstTrigger += new EventHandler(volumeBoxTrigger_FirstTrigger);
            volumeBoxTrigger.TimeOut += new EventHandler(volumeBoxTrigger_TimeOut);
            lockTrigger.TimeOut += new EventHandler(lockTrigger_TimeOut);
            removeTrigger.TimeOut += new EventHandler(removeTrigger_TimeOut);



            //SharpMedia.Importer.BeginImport += new EventHandler<MediaImporter.ImportEventArgs>(volumeScanner_ScanBegun);
            SharpMedia.Importer.EndCommit += new EventHandler(volumeScanner_ScanComplete);

            SharpMedia.Importer.BeginImport += new EventHandler<MediaImporter.ImportEventArgs>(Importer_BeginImport);
            SharpMedia.Importer.EndImport += new EventHandler<MediaImporter.ImportEventArgs>(Importer_EndImport);
            if (!Debugger.IsAttached)
            {
                SharpMedia.JobQueue.Enqueue(BeginImport);
            }


        }

        void Importer_EndImport(object sender, MediaImporter.ImportEventArgs e)
        {
            SharpMedia.JobQueue.Enqueue(VolumeEndedImport, e);
        }

        void Importer_BeginImport(object sender, MediaImporter.ImportEventArgs e)
        {
            SharpMedia.JobQueue.Enqueue(VolumeBeganImport, e);
        }

        void VolumeBeganImport(MediaImporter.ImportEventArgs e)
        {
            foreach (VolumeItem item in hdList)
            {
                if (item.Volume != e.Root.Volume)
                    continue;

                item.UpdateIcon.Fade(255, 6f);
            }
        }
        void VolumeEndedImport(MediaImporter.ImportEventArgs e)
        {
            foreach (VolumeItem item in hdList)
            {
                if (item.Volume != e.Root.Volume)
                    continue;

                item.UpdateIcon.Fade(0, 6f);
                item.MessageLabel.Text = string.Format("Import Complete\nAdded: {0} Removed: {1}", e.Added, e.Removed);
            }
        }



        void removeTrigger_TimeOut(object sender, EventArgs e)
        {
            volumeBoxTrigger.Trigger();
            for (int i = 0; i < hdList.Count; i++)
            {

                VolumeItem item = hdList.Get<VolumeItem>(i);

                if (!SharpMedia.RootManager.IsOnline(item.Volume))
                {
                    hdList.RemoveAt(i--);
                    hdBox.Add(item);
                    item.MovementSpeed = 3.1f;
                    item.Location += hdList.Location;
                    item.Destination = item.Location + new PointS(200, 0);
                }
            }
        }

        void volumeBoxTrigger_TimeOut(object sender, EventArgs e)
        {
            hdBox.Destination = new PointS(Size.Width, 0);
            foreach (VolumeItem item in hdList)
            {
                item.MessageLabel.Fade(0, 6f);
            }
        }

        void volumeBoxTrigger_FirstTrigger(object sender, EventArgs e)
        {
            hdBox.Destination = new PointS(Size.Width - 200, 0);
            foreach (VolumeItem item in hdList)
            {
                item.MessageLabel.Text = "";
                item.MessageLabel.Fade(255, 6f);
            }
        }


        public override void Update(TimeSpan ts)
        {
            volumeBoxTrigger.Update(ts);
            if (SharpMedia.Importer.ImportInProgress)
                volumeBoxTrigger.Trigger();

            /*foreach (VolumeItem item in hdList)
            {
                if (item.Disconnected)
                    continue;

                if (SharpMedia.Importer.ImportInProgress)
                    item.MessageLabel.Text = SharpMedia.Volumes.GetMessage(item.Volume);

                if (SharpMedia.Volumes.IsImporting(item.Volume))
                {
                    if (!item.Importing)
                        item.UpdateIcon.Fade(255, 6f);
                    item.Importing = true;
                }
                else if (!SharpMedia.Volumes.IsImporting(item.Volume) && item.Importing)
                {
                    item.MessageLabel.Text = SharpMedia.Volumes.GetMessage(item.Volume);
                    item.UpdateIcon.Fade(0, 6f);
                    item.Importing = false;
                }
            }*/


            base.Update(ts);
            lockTrigger.Update(ts);
            removeTrigger.Update(ts);
            if (hdList.Count != SharpMedia.RootManager.Roots.Count())
            {
                for (int i = 0; i < hdList.Count; i++)
                {
                    
                    VolumeItem item = hdList.Get<VolumeItem>(i);

                    if (!item.Disconnected && !SharpMedia.RootManager.IsOnline(item.Volume))
                    {
                        item.Disconnected = true;
                        removeTrigger.Trigger();
                    }
                }

                

                foreach(var root in SharpMedia.RootManager.Roots)
                {
                    //var item = hdList.Where(x => ((VolumeItem)x).Volume == volumes[i]).FirstOrDefault();
                    bool contained = false;
                    foreach (VolumeItem item in hdList)
                    {
                        if (item.Volume == root.Volume)
                        {
                            contained = true;
                            break ;
                        }
                    }
                    
                    if (!contained)
                    {
                        VolumeItem item = new VolumeItem(root.Volume);
                        hdList.Add(item);
                        hdList.DestinationSize = new SizeS(200, 70 * hdList.Count);
                        hdList.MoveItems(true);
                        item.Location = item.Destination + new PointS(400, 0);
                    }
                }
                hdList.DestinationSize = new SizeS(200, 70 * hdList.Count);
                hdList.MoveItems(true);
            }

            for (int i = 0; i < hdBox.Count; i++)
            {
                if (hdBox[i] is VolumeItem && !hdBox[i].IsMoving)
                    hdBox.RemoveAt(i--);
            }

        }


        void volumeScanner_ScanComplete(object sender, EventArgs e)
        {
            SharpMedia.WorkDone();
        }

        private void BeginImport()
        {
            SharpMedia.WaitForLock();
            volumeBoxTrigger.Trigger();
            SharpMedia.Importer.ScanVolumes();
        }

        private void BeginImport(System.IO.DriveInfo volume)
        {
            SharpMedia.WaitForLock();
            volumeBoxTrigger.Trigger();
            SharpMedia.Importer.ScanVolumes();
/*            string mediaRoot = SharpMedia.Volumes.FindMediaRoot(volume.RootDirectory.FullName, 2);
            if(mediaRoot != null)
                SharpMedia.Volumes.Scan();*/
        }

        void diskMonitor_DiskRemoved(object sender, System.IO.DriveInfo volume)
        {
            SharpMedia.RootManager.Refresh();
            SharpMedia.JobQueue.Enqueue(SharpMedia.NotifyMediaChanges);
            SharpMedia.JobQueue.Enqueue(volumeBoxTrigger.Trigger);
        }

        void diskMonitor_DiskFound(object sender, System.IO.DriveInfo volume)
        {
            SharpMedia.RootManager.Refresh();
            Util.RunAsync(BeginImport, volume);
            SharpMedia.JobQueue.Enqueue(volumeBoxTrigger.Trigger);
            SharpMedia.JobQueue.Enqueue(SharpMedia.NotifyMediaChanges);
        }

        protected override void MediaChanged(MediaDataSet obj)
        {
            base.MediaChanged(obj);
        }

        public override void Command(Lizk.SimpleHUD.HUDCommands command, object tag)
        {
            switch (command)
            {
                case HUDCommands.UpdateDatabase:
                    BeginImport();
                    break;
                case HUDCommands.Fullscreen:
                    bool isWindowed = SharpMedia.Engine.Windowed == WindowMode.Windowed;

                    if (isWindowed)
                        SharpMedia.Engine.Windowed = SharpMedia.Settings.UseExclusiveFullscreen ? WindowMode.ExclusiveFullscreen : WindowMode.Fullscreen;
                    else
                        SharpMedia.Engine.Windowed = WindowMode.Windowed;
                    //SharpMedia.Form.ResetDevice();
                    break;
                default:
                    break;
            }

        }

        private TripTrigger lockTrigger = new TripTrigger(new TimeSpan(0, 0, 1));

        public void InterfaceLocked()
        {
            lockTrigger.Trigger();
            
        }

        void lockTrigger_TimeOut(object sender, EventArgs e)
        {
            background.Fade(127, 2f);
        }

        public void InterfaceUnlocked()
        {
            lockTrigger.Stop(false);
            warningBox.Fade(0, 2f);
            background.Fade(0, 2f);
        }

        public void ShowLockedWarning()
        {
            warningBox.Fade(255, 2f);
        }

        private class VolumeItem : HUDContainerSimple
        {
            public HUDLabel MessageLabel { get; set; }
            public HUDImage UpdateIcon { get; set; }
            public string Volume { get; private set; }
            public bool Importing { get; set; }
            public VolumeItem(string volume)
            {
                this.Volume = volume;
                InitalizeComponents();
            }
            private bool disconnected;
            public bool Disconnected {
                get
                {
                    return disconnected;
                }
                set
                {
                    disconnected = value;
                    if (value)
                    {
                        HDImage.Color = ColorS.Red;
                        MessageLabel.Text = "Disconnected...";
                    }
                    else
                    {
                        HDImage.Color = ColorS.White;
                    }
                }
            }
            HUDImage HDImage;
            public void InitalizeComponents()
            {

                Size = new SizeS(200, 70);
                Anchor = Anchor.Top | Anchor.Right;
                MovementSpeed = 5f;

                HUDImage hdBg = new HUDImage("selection.png");
                hdBg.Size = new SizeS(400, 64);
                hdBg.Location = new PointS(0, 2);
                Add(hdBg);

                HDImage = new HUDImage("harddisk.png");
                HDImage.Size = new SizeS(60, 60);
                HDImage.Location = new PointS(2, 4);
                Add(HDImage);

                HUDLabel VolumeLabel = new HUDLabel(Volume, "tahoma14b");
                VolumeLabel.Bounds = new RectangleS(HDImage.Bounds.Right + 2, HDImage.Bounds.Top + 4, 138, 30);
                VolumeLabel.WordBreak = false;
                Add(VolumeLabel);

                UpdateIcon = new HUDImage("import.png");
                UpdateIcon.Size = new SizeS(30, 30);
                UpdateIcon.Location = new PointS(32, 34);
                UpdateIcon.Alpha = 0;
                UpdateIcon.FadeOnLoad = false;
                Add(UpdateIcon);

                MessageLabel = new HUDLabel("", "tahoma12b");
                MessageLabel.Bounds = new RectangleS(HDImage.Bounds.Right + 10, HDImage.Bounds.Top + 20, 130, 34);
                MessageLabel.Alpha = 255;
                Add(MessageLabel);

            }
        }

    }

   

}
